home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / net / res_debug.c < prev    next >
C/C++ Source or Header  |  1988-07-29  |  10KB  |  487 lines

  1. /*
  2.  * Copyright (c) 1985 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #if defined(LIBC_SCCS) && !defined(lint)
  14. static char sccsid[] = "@(#)res_debug.c    5.23 (Berkeley) 5/19/88";
  15. #endif /* LIBC_SCCS and not lint */
  16.  
  17. #if defined(lint) && !defined(DEBUG)
  18. #define DEBUG
  19. #endif
  20.  
  21. #include <sys/types.h>
  22. #include <netinet/in.h>
  23. #include <stdio.h>
  24. #include <arpa/nameser.h>
  25.  
  26. extern char *p_cdname(), *p_rr(), *p_type(), *p_class(), *p_time();
  27. extern char *inet_ntoa();
  28.  
  29. char *_res_opcodes[] = {
  30.     "QUERY",
  31.     "IQUERY",
  32.     "CQUERYM",
  33.     "CQUERYU",
  34.     "4",
  35.     "5",
  36.     "6",
  37.     "7",
  38.     "8",
  39.     "UPDATEA",
  40.     "UPDATED",
  41.     "UPDATEDA",
  42.     "UPDATEM",
  43.     "UPDATEMA",
  44.     "ZONEINIT",
  45.     "ZONEREF",
  46. };
  47.  
  48. char *_res_resultcodes[] = {
  49.     "NOERROR",
  50.     "FORMERR",
  51.     "SERVFAIL",
  52.     "NXDOMAIN",
  53.     "NOTIMP",
  54.     "REFUSED",
  55.     "6",
  56.     "7",
  57.     "8",
  58.     "9",
  59.     "10",
  60.     "11",
  61.     "12",
  62.     "13",
  63.     "14",
  64.     "NOCHANGE",
  65. };
  66.  
  67. p_query(msg)
  68.     char *msg;
  69. {
  70. #ifdef DEBUG
  71.     fp_query(msg,stdout);
  72. #endif
  73. }
  74.  
  75. /*
  76.  * Print the contents of a query.
  77.  * This is intended to be primarily a debugging routine.
  78.  */
  79. fp_query(msg,file)
  80.     char *msg;
  81.     FILE *file;
  82. {
  83. #ifdef DEBUG
  84.     register char *cp;
  85.     register HEADER *hp;
  86.     register int n;
  87.  
  88.     /*
  89.      * Print header fields.
  90.      */
  91.     hp = (HEADER *)msg;
  92.     cp = msg + sizeof(HEADER);
  93.     fprintf(file,"HEADER:\n");
  94.     fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
  95.     fprintf(file,", id = %d", ntohs(hp->id));
  96.     fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
  97.     fprintf(file,"\theader flags: ");
  98.     if (hp->qr)
  99.         fprintf(file," qr");
  100.     if (hp->aa)
  101.         fprintf(file," aa");
  102.     if (hp->tc)
  103.         fprintf(file," tc");
  104.     if (hp->rd)
  105.         fprintf(file," rd");
  106.     if (hp->ra)
  107.         fprintf(file," ra");
  108.     if (hp->pr)
  109.         fprintf(file," pr");
  110.     fprintf(file,"\n\tqdcount = %d", ntohs(hp->qdcount));
  111.     fprintf(file,", ancount = %d", ntohs(hp->ancount));
  112.     fprintf(file,", nscount = %d", ntohs(hp->nscount));
  113.     fprintf(file,", arcount = %d\n\n", ntohs(hp->arcount));
  114.     /*
  115.      * Print question records.
  116.      */
  117.     if (n = ntohs(hp->qdcount)) {
  118.         fprintf(file,"QUESTIONS:\n");
  119.         while (--n >= 0) {
  120.             fprintf(file,"\t");
  121.             cp = p_cdname(cp, msg, file);
  122.             if (cp == NULL)
  123.                 return;
  124.             fprintf(file,", type = %s",
  125.                 p_type((int) _getshort((u_char *) cp)));
  126.             cp += sizeof(u_short);
  127.             fprintf(file,", class = %s\n\n",
  128.                 p_class((int) (_getshort((u_char *) cp))));
  129.             cp += sizeof(u_short);
  130.         }
  131.     }
  132.     /*
  133.      * Print authoritative answer records
  134.      */
  135.     if (n = ntohs(hp->ancount)) {
  136.         fprintf(file,"ANSWERS:\n");
  137.         while (--n >= 0) {
  138.             fprintf(file,"\t");
  139.             cp = p_rr(cp, msg, file);
  140.             if (cp == NULL)
  141.                 return;
  142.         }
  143.     }
  144.     /*
  145.      * print name server records
  146.      */
  147.     if (n = ntohs(hp->nscount)) {
  148.         fprintf(file,"NAME SERVERS:\n");
  149.         while (--n >= 0) {
  150.             fprintf(file,"\t");
  151.             cp = p_rr(cp, msg, file);
  152.             if (cp == NULL)
  153.                 return;
  154.         }
  155.     }
  156.     /*
  157.      * print additional records
  158.      */
  159.     if (n = ntohs(hp->arcount)) {
  160.         fprintf(file,"ADDITIONAL RECORDS:\n");
  161.         while (--n >= 0) {
  162.             fprintf(file,"\t");
  163.             cp = p_rr(cp, msg, file);
  164.             if (cp == NULL)
  165.                 return;
  166.         }
  167.     }
  168. #endif
  169. }
  170.  
  171. char *
  172. p_cdname(cp, msg, file)
  173.     char *cp, *msg;
  174.     FILE *file;
  175. {
  176. #ifdef DEBUG
  177.     char name[MAXDNAME];
  178.     int n;
  179.  
  180.     if ((n = dn_expand((u_char *) msg, (u_char *) (msg + 512),
  181.         (u_char *) cp, (u_char *) name, sizeof(name))) < 0)
  182.         return (NULL);
  183.     if (name[0] == '\0') {
  184.         name[0] = '.';
  185.         name[1] = '\0';
  186.     }
  187.     fputs(name, file);
  188.     return (cp + n);
  189. #endif
  190. }
  191.  
  192. /*
  193.  * Print resource record fields in human readable form.
  194.  */
  195. char *
  196. p_rr(cp, msg, file)
  197.     char *cp, *msg;
  198.     FILE *file;
  199. {
  200. #ifdef DEBUG
  201.     int type, class, dlen, n, c;
  202.     struct in_addr inaddr;
  203.     char *cp1;
  204.  
  205.     if ((cp = p_cdname(cp, msg, file)) == NULL)
  206.         return (NULL);            /* compression error */
  207.     fprintf(file,"\n\ttype = %s", p_type(type = _getshort((u_char *)cp)));
  208.     cp += sizeof(u_short);
  209.     fprintf(file,", class = %s", p_class(class = _getshort((u_char *)cp)));
  210.     cp += sizeof(u_short);
  211.     fprintf(file,", ttl = %s", p_time((u_long) cp));
  212.     cp += sizeof(u_long);
  213.     fprintf(file,", dlen = %d\n", dlen = _getshort((u_char *)cp));
  214.     cp += sizeof(u_short);
  215.     cp1 = cp;
  216.     /*
  217.      * Print type specific data, if appropriate
  218.      */
  219.     switch (type) {
  220.     case T_A:
  221.         switch (class) {
  222.         case C_IN:
  223.             bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  224.             if (dlen == 4) {
  225.                 fprintf(file,"\tinternet address = %s\n",
  226.                     inet_ntoa(inaddr));
  227.                 cp += dlen;
  228.             } else if (dlen == 7) {
  229.                 fprintf(file,"\tinternet address = %s",
  230.                     inet_ntoa(inaddr));
  231.                 fprintf(file,", protocol = %d", cp[4]);
  232.                 fprintf(file,", port = %d\n",
  233.                     (cp[5] << 8) + cp[6]);
  234.                 cp += dlen;
  235.             }
  236.             break;
  237.         default:
  238.             cp += dlen;
  239.         }
  240.         break;
  241.     case T_CNAME:
  242.     case T_MB:
  243. #ifdef OLDRR
  244.     case T_MD:
  245.     case T_MF:
  246. #endif /* OLDRR */
  247.     case T_MG:
  248.     case T_MR:
  249.     case T_NS:
  250.     case T_PTR:
  251.         fprintf(file,"\tdomain name = ");
  252.         cp = p_cdname(cp, msg, file);
  253.         fprintf(file,"\n");
  254.         break;
  255.  
  256.     case T_HINFO:
  257.         if (n = *cp++) {
  258.             fprintf(file,"\tCPU=%.*s\n", n, cp);
  259.             cp += n;
  260.         }
  261.         if (n = *cp++) {
  262.             fprintf(file,"\tOS=%.*s\n", n, cp);
  263.             cp += n;
  264.         }
  265.         break;
  266.  
  267.     case T_SOA:
  268.         fprintf(file,"\torigin = ");
  269.         cp = p_cdname(cp, msg, file);
  270.         fprintf(file,"\n\tmail addr = ");
  271.         cp = p_cdname(cp, msg, file);
  272.         fprintf(file,"\n\tserial=%ld", _getlong((u_char *)cp));
  273.         cp += sizeof(u_long);
  274.         fprintf(file,", refresh=%s", p_time((u_long) cp));
  275.         cp += sizeof(u_long);
  276.         fprintf(file,", retry=%s", p_time((u_long) cp));
  277.         cp += sizeof(u_long);
  278.         fprintf(file,", expire=%s", p_time((u_long) cp));
  279.         cp += sizeof(u_long);
  280.         fprintf(file,", min=%s\n", p_time((u_long) cp));
  281.         cp += sizeof(u_long);
  282.         break;
  283.  
  284.     case T_MX:
  285.         fprintf(file,"\tpreference = %ld,",_getshort((u_char *)cp));
  286.         cp += sizeof(u_short);
  287.         fprintf(file," name = ");
  288.         cp = p_cdname(cp, msg, file);
  289.         break;
  290.  
  291.     case T_MINFO:
  292.         fprintf(file,"\trequests = ");
  293.         cp = p_cdname(cp, msg, file);
  294.         fprintf(file,"\n\terrors = ");
  295.         cp = p_cdname(cp, msg, file);
  296.         break;
  297.  
  298.     case T_UINFO:
  299.         fprintf(file,"\t%s\n", cp);
  300.         cp += dlen;
  301.         break;
  302.  
  303.     case T_UID:
  304.     case T_GID:
  305.         if (dlen == 4) {
  306.             fprintf(file,"\t%ld\n", _getlong((u_char *) cp));
  307.             cp += sizeof(int);
  308.         }
  309.         break;
  310.  
  311.     case T_WKS:
  312.         if (dlen < sizeof(u_long) + 1)
  313.             break;
  314.         bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  315.         cp += sizeof(u_long);
  316.         fprintf(file,"\tinternet address = %s, protocol = %d\n\t",
  317.             inet_ntoa(inaddr), *cp++);
  318.         n = 0;
  319.         while (cp < cp1 + dlen) {
  320.             c = *cp++;
  321.             do {
  322.                  if (c & 0200)
  323.                     fprintf(file," %d", n);
  324.                  c <<= 1;
  325.             } while (++n & 07);
  326.         }
  327.         putc('\n',file);
  328.         break;
  329.  
  330. #ifdef ALLOW_T_UNSPEC
  331.     case T_UNSPEC:
  332.         {
  333.             int NumBytes = 8;
  334.             char *DataPtr;
  335.             int i;
  336.  
  337.             if (dlen < NumBytes) NumBytes = dlen;
  338.             fprintf(file, "\tFirst %d bytes of hex data:",
  339.                 NumBytes);
  340.             for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
  341.                 fprintf(file, " %x", *DataPtr);
  342.             fputs("\n", file);
  343.             cp += dlen;
  344.         }
  345.         break;
  346. #endif /* ALLOW_T_UNSPEC */
  347.  
  348.     default:
  349.         fprintf(file,"\t???\n");
  350.         cp += dlen;
  351.     }
  352.     if (cp != cp1 + dlen)
  353.         fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen);
  354.     fprintf(file,"\n");
  355.     return (cp);
  356. #endif
  357. }
  358.  
  359. static    char nbuf[40];
  360.  
  361. /*
  362.  * Return a string for the type
  363.  */
  364. char *
  365. p_type(type)
  366.     int type;
  367. {
  368.     switch (type) {
  369.     case T_A:
  370.         return("A");
  371.     case T_NS:        /* authoritative server */
  372.         return("NS");
  373. #ifdef OLDRR
  374.     case T_MD:        /* mail destination */
  375.         return("MD");
  376.     case T_MF:        /* mail forwarder */
  377.         return("MF");
  378. #endif /* OLDRR */
  379.     case T_CNAME:        /* connonical name */
  380.         return("CNAME");
  381.     case T_SOA:        /* start of authority zone */
  382.         return("SOA");
  383.     case T_MB:        /* mailbox domain name */
  384.         return("MB");
  385.     case T_MG:        /* mail group member */
  386.         return("MG");
  387.     case T_MX:        /* mail routing info */
  388.         return("MX");
  389.     case T_MR:        /* mail rename name */
  390.         return("MR");
  391.     case T_NULL:        /* null resource record */
  392.         return("NULL");
  393.     case T_WKS:        /* well known service */
  394.         return("WKS");
  395.     case T_PTR:        /* domain name pointer */
  396.         return("PTR");
  397.     case T_HINFO:        /* host information */
  398.         return("HINFO");
  399.     case T_MINFO:        /* mailbox information */
  400.         return("MINFO");
  401.     case T_AXFR:        /* zone transfer */
  402.         return("AXFR");
  403.     case T_MAILB:        /* mail box */
  404.         return("MAILB");
  405.     case T_MAILA:        /* mail address */
  406.         return("MAILA");
  407.     case T_ANY:        /* matches any type */
  408.         return("ANY");
  409.     case T_UINFO:
  410.         return("UINFO");
  411.     case T_UID:
  412.         return("UID");
  413.     case T_GID:
  414.         return("GID");
  415. #ifdef ALLOW_T_UNSPEC
  416.     case T_UNSPEC:
  417.         return("UNSPEC");
  418. #endif /* ALLOW_T_UNSPEC */
  419.     default:
  420.         (void)sprintf(nbuf, "%d", type);
  421.         return(nbuf);
  422.     }
  423. }
  424.  
  425. /*
  426.  * Return a mnemonic for class
  427.  */
  428. char *
  429. p_class(class)
  430.     int class;
  431. {
  432.  
  433.     switch (class) {
  434.     case C_IN:        /* internet class */
  435.         return("IN");
  436.     case C_ANY:        /* matches any class */
  437.         return("ANY");
  438.     default:
  439.         (void)sprintf(nbuf, "%d", class);
  440.         return(nbuf);
  441.     }
  442. }
  443.  
  444. /*
  445.  * Return a mnemonic for a time to live
  446.  */
  447. char
  448. *p_time(value)
  449.     u_long value;
  450. {
  451.     int secs, mins, hours;
  452.     register char *p;
  453.  
  454.     secs = value % 60;
  455.     value /= 60;
  456.     mins = value % 60;
  457.     value /= 60;
  458.     hours = value % 24;
  459.     value /= 24;
  460.  
  461. #define    PLURALIZE(x)    x, (x == 1) ? "" : "s"
  462.     p = nbuf;
  463.     if (value) {
  464.         (void)sprintf(p, "%d day%s", PLURALIZE(value));
  465.         while (*++p);
  466.     }
  467.     if (hours) {
  468.         if (p != nbuf)
  469.             *p++ = ' ';
  470.         (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
  471.         while (*++p);
  472.     }
  473.     if (mins) {
  474.         if (p != nbuf)
  475.             *p++ = ' ';
  476.         (void)sprintf(p, "%d min%s", PLURALIZE(mins));
  477.         while (*++p);
  478.     }
  479.     if (secs) {
  480.         if (p != nbuf)
  481.             *p++ = ' ';
  482.         (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
  483.         while (*++p);
  484.     }
  485.     return(nbuf);
  486. }
  487.